package net.lwf.file.util;

import java.io.File;
import java.io.FileFilter;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;

public class FileHandler {
	
	public static final String create_file = "/eclipse/out/infile_landscape.pdf";
	
	
	public static void main(String[] args) {
		//createFile(create_file);
		//deleteFile(create_file);
		createFile("/eclipse/out/1/2", "/eclipse/out/1/2/test.pdf");
	}

	//--------------------------------------------------------------------------------------------------------
	//	Basic file operations
	//--------------------------------------------------------------------------------------------------------
	/**
	 * Creates a file.
	 * 
	 * @param filename Fully qualified file name
	 */
	public static void createFile(String directory, String filename) {

		File dir = new File(directory);  
			boolean success = dir.mkdirs();
			createFile(filename);
	}
	
	/**
	 * Creates a file.
	 * 
	 * @param filename Fully qualified file name
	 */
	public static void createFile(String filename) {
		try { 
			File file = new File(filename); // Create file if it does not exist 
			boolean success = file.createNewFile(); 
			if (success) { 
				// File did not exist and was created 
			} else { 
				// File already exists 
			} 
		} catch (IOException e) { 
			e.printStackTrace();
		} 

	}

	/**
	 * Deletes a file.
	 * 
	 * @param filename Fully qualified file name
	 */
	public static void deleteFile(String filename) {
		File file = new File(filename); 
		if (file.exists()) { 
			// File or directory exists 
			file.delete();
		} 
	}
	
	/**
	 * Copies a file from one location to another.
	 * 
	 * @param srcfile 	Fully qualified source file name
	 * @param destfile 	Fully qualified destination file name
	 */
	public static void copyFile(String srcfile, String destfile) throws IOException {
		
		InputStream in = new FileInputStream(srcfile); 
		OutputStream out = new FileOutputStream(destfile); 
		// Transfer bytes from in to out 
		byte[] buf = new byte[1024]; 
		int len; 
		while ((len = in.read(buf)) > 0) { 
			out.write(buf, 0, len); 
		} 
		in.close(); 
		out.close(); 
	}

	/**
	 * Gets the file size.
	 * 
	 * @param filename Fully qualified file name
	 */
	public static long getFileSize(String filename) {
		File file = new File(filename); 
		if (file.exists()) { 
			return file.length();
		}
		return 0;
	}
	/**
	 * Moves a file from one location to another.
	 * 
	 * @param srcfile 	Fully qualified source file name
	 * @param destfile 	Fully qualified destination file name
	 */	
	public static void move(String srcfile, String destfile) {
		// File (or directory) to be moved 
		File source = new File(srcfile); 
		// Destination directory 
		File destination = new File(destfile); 
		// Move file to new directory 
		boolean success = source.renameTo(new File(destination, source.getName())); 
		if (!success) { 
			// File was not successfully moved 
		} 
		
	}

    public static String[] getAllFiles(String strDir) {
        String a_strFiles[] = (String[])null;
        File allFiles = new File(strDir);
        if(allFiles.isDirectory())
            a_strFiles = allFiles.list();
        return a_strFiles;
    }
    
    public static void rename() {
    	String RENAME = "new_";
    	String[] files = getAllFiles("C:/downloads/common");
    	for(int i=0; i<files.length; i++) {
    		File file = new File(files[i]);
    		if(file.isFile()) {
    			File renamefile = new File(RENAME + files[i]);
    			file.renameTo(renamefile);
    		}
    	}
    }
    
    public static Map<String, String[]> getAllFileLocations(String strDir) {
        Map<String, String[]> mapFiles = new HashMap<String, String[]>();
        File allFiles = new File(strDir);
        String directory = "base";
        if(allFiles.isDirectory()) {
        	directory = allFiles.getName();
        	mapFiles.put(directory,allFiles.list());
        }
       // else {
        	
      //  }
            
        return mapFiles;
    }    

    /**
     * Writes the contents to the file.
     * If the outFlush is true, adds the contents at the end otherwise, wipes all content and
     * adds new content.
     * 
     * @param fileName
     * @param contents
     * @param autoFlush boolean value
     */
    public static void writeToFile(String fileName, String contents, boolean autoFlush) {
        PrintWriter pWriter = null;
        try
        {
            pWriter = new PrintWriter(new FileWriter(fileName, autoFlush));
            pWriter.println(contents);
            pWriter.close();
        }
        catch(IOException ioexception) { }
    }
    
    public static void printFileProperties(File file) {
    	System.out.println("==========> File Name: " + file.getName());
    	System.out.println("==========> File Path: " + file.getPath());
    	System.out.println("==========> Parent: " + file.getParent());
    	System.out.println("==========> Absolute Path: " + file.getAbsolutePath());
    	try {
    		System.out.println("==========> Canonical Path: " + file.getCanonicalPath());
    	}
    	catch(Exception ex) {
    		
    	}
    	
    	System.out.println("==========> Is a file?: " + file.isFile());

    }
    
    ////
    
    /**
     * Used to list the files / subdirectories in a given directory.
     * @param dir Directory to start listing from
     */
    public static void doSimpleFileListing(String dirName) {

        System.out.println();
        System.out.println("Simple file listing...");
        System.out.println("----------------------");

        File dir = new File(dirName);
        
        String[] children = dir.list();

        printFiles(children, dirName);

    }
    
    /**
     * Used to list the files / subdirectories in a given directory and also
     * provide a filter class.
     * @param dir Directory to start listing from
     * @param ff  A string that can be used to filter out files from the
     *            returned list of files. In this example, the String
     *            values is used to only return those values that start
     *            with the given String.
     */
    public static void doFileFilterListing(String dirName, String ff) {

        System.out.println("Filter file listing...");
        System.out.println("----------------------");

        final String fileFilter = ff;

        File           dir     = new File(dirName);
        FilenameFilter filter  = null;

        if (fileFilter != null) {

            // It is also possible to filter the list of returned files.
            // This example uses the passed in String value (if any) to only
            // list those files that start with the given String.
            filter = new FilenameFilter() {
                public boolean accept(File dir, String name) {
                    return name.startsWith(fileFilter);
                }
            };
        }

        String[] children = dir.list(filter);

        printFiles(children, dirName);

    }
    
    /**
     * Used to list the files / subdirectories in a given directory and also
     * provide a filter class that only lists the directories.
     * @param dir Directory to start listing from
     */
    public static void doFileFilterDirectoryListing(String dirName) {

        System.out.println("Filter Directory listing...");
        System.out.println("---------------------------");

        File dir = new File(dirName);

        // The list of files can also be retrieved as File objects. In this
        // case, we are just listing all files in the directory. For the sake
        // of this example, we will not print them out here.
        File[] files = (new File(dirName)).listFiles();

        // This filter only returns directories
        FileFilter dirFilter = new FileFilter() {
            public boolean accept(File dir) {
                return dir.isDirectory();
            }
        };

        files = dir.listFiles(dirFilter);

        for (int i=0; i<files.length; i++) {
            System.out.println("[D] : " + files[i]);
        }
        System.out.println();


    }    
    
    
    /**
     * Utility method to print the list of files to the terminal
     * @param children A String array of the file names to print out
     * @param dirName  The given directory to start the listing at.
     */
    private static void printFiles(String[] children, String dirName) {

        if (children == null) {
            System.out.println("Error with " + dirName);
            System.out.println("Either directory does not exist or is not a directory");
        } else {
            for (int i=0; i<children.length; i++) {
                // Get filename of file or directory
                String filename = children[i];
                if ((new File(dirName + File.separatorChar + filename)).isDirectory()) {
                    System.out.print("[D] : ");
                } else {
                    System.out.print("[F] : ");
                }
                System.out.println(dirName + File.separatorChar + filename);
            }
        }
        System.out.println();

    }    
    
}
